---
sidebar_position: 2
---

# Optimization guidelines

## Use `React.memo()`
It is recommended to wrap all cell components in `React.memo()` to avoid un-necessary renders (except for very light
components where a re-render is faster than a props check):
```tsx
const MyComponent = React.memo(({ rowData, setRowData }) => {
  return <input {/*...*/} />
})

const column = { component: MyComponent, /*...*/ }
```

## Use `keyColumn`
Cell components are re-rendered only when their props change thanks to `React.memo()`. But because they take the entire
row object in the prop `rowData` (and not just the value they are interested in), all cells of a row are re-rendered when
the user edits a single cell.

To make this obvious consider the following text-typed column:
```tsx
// Do not do this 👎
const TextComponent = React.memo(
  ({ rowData, setRowData, columnData }) => {
    return (
      <input
        value={rowData[columnData]}
        onChange={(e) => setRowData({ ...rowData, [columnData]: e.target.value })}
      />
    )
  }
)

const textColumn = (key) => ({
  component: TextComponent,
  columnData: key,
  deleteValue: ({ rowData }) => ({ ...rowData, [key]: '' }),
  copyValue: ({ rowData }) => rowData[key],
  pasteValue: ({ rowData, value }) => ({ ...rowData, [key]: value }),
})

const columns = [
  { ...textColumn('firstName') },
  { ...textColumn('lastName') },
]
```

The `rowData` prop of the firstName column will change every time the user changes the lastName (and vice-versa),
triggering an un-necessary re-render of the firstName column. And this happens on every keystroke!

Fortunately this can easily be avoided by using the built-in `keyColumn`.
```tsx
import { keyColumn } from 'react-datasheet-grid'

const TextComponent = React.memo(
  ({ rowData, setRowData }) => {
    return (
      <input
        value={rowData}
        onChange={(e) => setRowData(e.target.value)}
      />
    )
  }
)

const textColumn = {
  component: TextComponent,
  deleteValue: () => '',
  copyValue: ({ rowData }) => rowData,
  pasteValue: ({ value }) => value,
}

const columns = [
  { ...keyColumn('firstName', textColumn) }
  { ...keyColumn('lastName', textColumn) }
]
```
`keyColumn` has the advantage of reducing the number of renders your component has to perform while also
making it much easier to write.
